import struct
import os
import socket

from chat.common.RSA_file import *
from chat.client.client_database import *
import chat.client.gol
from chat.common.OTP import OTP_encryption


def get_socket_auth():
    print(chat.client.gol.get_value("socket_obj"))
    return chat.client.gol.get_value("socket_obj")


def socket_send_msg(room_id, send_msg, OTP_flag):
    """
    发消息给room
    :param room_id: 目标room id
    :param send_msg: 要发送的数据
    :param OTP_flag: 一次一密标志位
    :return:
    """

    server = get_socket_auth()
    user_name = chat.client.gol.get_value("socket_username")
    user_id = get_user_id(user_name)
    # 数据库
    print("sender.26", user_name, room_id)
    pubk = int(return_room_public_key(user_name, room_id))
    n = int(return_room_private_key_n(user_name, room_id))

    if OTP_flag == 0:
        flag = b'\x00'
    elif OTP_flag == 1:
        flag = b'\x01'
        # 一次一密加密
        if chat.client.gol.get_value("OTP_key") == None:
            chat.client.gol.set_value("OTP_key", 'BUPT_Chat_default')  # 默认初始密钥
        send_msg = OTP_encryption(send_msg)
    enc_msg = message_encryption(send_msg, pubk, n).encode()
    len_msg = len(enc_msg)
    data_head = struct.pack("<HHQ", room_id, user_id, len_msg)

    data = data_head + enc_msg + flag

    head = struct.pack("<i", len(data)) + b'\x05\x00\x00\x00'
    msg = head + data

    server.send(msg)
    # get_recv(server)

def socket_send_file(filepath,room_id):

    server = get_socket_auth()
    sender_id = get_user_id(chat.client.gol.get_value("socket_username"))

    # 判断是否为文件
    if os.path.isfile(filepath):
        # 定义文件头信息，包含文件名和文件大小
        file_head = struct.pack('<HHHl', room_id, sender_id, len(os.path.basename(filepath)), os.stat(filepath).st_size)
        file_head += os.path.basename(filepath).encode()
        head = struct.pack("<i", len(file_head)) + b'\x09\x00\x00\x00'

        # 发送文件名称与文件大小
        server.send(head+file_head)

        # 将传输文件以二进制的形式分多次上传至服务器
        fp = open(filepath, 'rb')
        while 1:
            data = fp.read(1024)
            if not data:
                print ('{0} file send over...'.format(os.path.basename(filepath)))
                break
            server.send(data)


def socket_send_exit():           # 退出登录
    print("==========exit=========")

    username = chat.client.gol.get_value("socket_username")
    user_id = get_user_id(username)

    server = get_socket_auth()
    data = struct.pack("<H", user_id) + str.encode("exit")
    head = struct.pack("<i", len(data)) + b'\x08\x00\x00\x00'
    msg = head + data

    # 加密用户与聊天室密钥
    if chat.client.gol.get_value("login_flag") == "username":
        passwd = chat.client.gol.get_value("plain_passwd")
        encrypt_private_key_bypwd(username, passwd)
        encrypt_room_private_key(username, "username")

    elif chat.client.gol.get_value("login_flag") == "email":
        email = chat.client.gol.get_value("socket_email")
        encrypt_private_key_byemail(username, email)
        encrypt_room_private_key(username, "email")

    server.send(msg)
    server.close()


def socket_send_rm_room(room_list):
    """
    发送要删除的room
    4bytes_len + \x0A\x00\x00\x00 + room_id_num[4bytes] + room_id[2bytes]* room_id_num
    :param room_list: [1,2,3]
    :return:
    """
    server = get_socket_auth()
    rm_room_data = b""
    room_num = 0
    for room_id in room_list:
        rm_room_data += struct.pack("<H", room_id)
        room_num += 1
    room_num = struct.pack("<i", room_num)
    data = room_num + rm_room_data
    head = struct.pack("<i", len(data)) + b'\x0A\x00\x00\x00'
    msg = head + data
    print("room_num ==>", room_num)
    print("rm_room_data ==>", rm_room_data)
    print("msg ==>", msg)
    server.send(msg)
